#!/usr/bin/env python
# -*- coding:utf-8 -*-
import datetime

from controller.verifyMailController import VerifyMailController
import random
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.utils import formataddr
from flask import current_app
from utils.loggings import loggings
from utils.response_code import RET, error_map_EN


class VerifyMailService(VerifyMailController):
    title = "验证您的邮箱"
    content = '''<div align="left" style="text-align: justify;"><font color="black" face="Arial" size="2" style="font-family: Arial;"><span style="font-size: 10pt;">验证您的邮箱：{}</span></font><div><br><br>'''

    # 初始化邮件客户端
    @classmethod
    def set_server(cls):
        cls.server = smtplib.SMTP("smtp.office365.com", 587, timeout=10)
        cls.server.connect("smtp.office365.com")
        cls.server.starttls()
        cls.server.login(current_app.config["EMAIL_SENDER"], current_app.config["EMAIL_PASSWORD"])

    # 发送邮件
    @classmethod
    def send(cls, target_email):
        cls.set_server()
        try:
            msg = MIMEMultipart()
            msg['From'] = formataddr(["", current_app.config["EMAIL_SENDER"]])
            msg['To'] = formataddr(["", target_email])
            msg['Subject'] = cls.title
            # 邮件正文内容
            verify_code = cls.verify_code()
            mail_body = cls.content.format(verify_code)
            # 组装邮件内容和标题，中文需参数‘utf-8’，单字节字符不需要
            body = MIMEText(mail_body, 'html', 'utf-8')
            msg.attach(body)

            cls.server.sendmail(current_app.config["EMAIL_SENDER"], [target_email, ], msg.as_string())
            cls.server.close()
            # 保存邮箱验证码
            res = cls.add(mail_verify_code=verify_code, mail=target_email)
            return res

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.IOERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}

    # 生成邮箱验证码
    @classmethod
    def verify_code(cls):
        code = random.sample('abcdefghijklmnopqrstuvwxyz' + '0123456789' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 4) + \
               random.sample('0123456789', 1) + \
               random.sample('abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '0123456789', 3)
        return "".join(code)

    # 检查邮箱验证码是否匹配
    @classmethod
    def check_verify_code(cls, mail_verify_id, mail_verify_code, email):
        try:
            verify_mail_result = cls.get(mail_verify_id=mail_verify_id)
            if verify_mail_result['code'] != RET.OK or verify_mail_result['totalCount'] == 0:
                return {'code': RET.DATAERR, 'message': '邮箱验证失败', 'data': None}

            verify_mail_time = verify_mail_result['data'][0]['create_time']
            verify_mail_time = datetime.datetime.strptime(verify_mail_time, "%Y-%m-%d %H:%M:%S")
            # 匹配验证码 以及验证码是否过期
            if verify_mail_result['data'][0]['mail_verify_code'] == mail_verify_code and \
                    verify_mail_result['data'][0]['mail'] == email and \
                    0 <= (datetime.datetime.now() - verify_mail_time).total_seconds() <= float(
                current_app.config["EMAIL_VERIFY_EXPIRES"]):
                cls.delete(mail_verify_id=mail_verify_id)
                return {'code': RET.OK, 'message': '验证成功', 'data': verify_mail_result}
            else:
                return {'code': RET.DATAERR, 'message': '邮箱验证码错误或过期', 'data': None}

        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DATAERR, 'message': '邮箱验证码获取异常', 'data': None}
